package logic

import (
	"061/Sgame/constant"
	"061/Sgame/db"
	"061/Sgame/server/common"
	"061/Sgame/server/game/global"
	"061/Sgame/server/game/model"
	"061/Sgame/server/game/model/data"
	"061/Sgame/utils"
	"log"
	"sync"
)

var ArmyService = &armyService{
	updateArmyChan: make(chan *data.Army, 100),
	arriveArmyChan: make(chan *data.Army, 100),
	giveUpIdChan:   make(chan int, 100),
	endTimeArmys:   make(map[int64][]*data.Army),
	passByPosArmys: make(map[int]map[int]*data.Army),
	stopInPosArmys: make(map[int]map[int]*data.Army),
	//sys: NewSysArmy(),
}

type armyService struct {
	passBy         sync.RWMutex
	updateArmyChan chan *data.Army
	arriveArmyChan chan *data.Army

	giveUpIdChan chan int
	//驻守的军队 key posId rid 军队
	stopInPosArmys map[int]map[int]*data.Army
	//缓存到达时间 军队
	endTimeArmys   map[int64][]*data.Army
	passByPosArmys map[int]map[int]*data.Army //玩家路过位置的军队 key:posId,armyId
	//sys *sysArmyService
}

// GetArmys 根据角色ID 获取军队
func (r *armyService) GetArmys(rid int) ([]model.Army, error) {
	var arms []data.Army
	err := db.GormDB.Where("rid=?", rid).Find(&arms).Error
	if err != nil {
		log.Println("军队查询出错", err)
		return nil, common.New(constant.DBError, "军队查询出错")
	}
	modelMrs := make([]model.Army, 0)
	for _, v := range arms {
		modelMrs = append(modelMrs, v.ToModel().(model.Army))
	}
	return modelMrs, nil
}

// GetArmysByCity 军队根据rid和cityid查询
func (r *armyService) GetArmysByCity(rid, cityid int) ([]model.Army, error) {
	var arms []data.Army
	err := db.GormDB.Where("rid=? and cityId=?", rid, cityid).Find(&arms).Error
	if err != nil {
		log.Println("军队查询出错", err)
		return nil, common.New(constant.DBError, "军队查询出错")
	}
	modelarms := make([]model.Army, 0)
	for _, v := range arms {
		modelarms = append(modelarms, v.ToModel().(model.Army))
	}
	return modelarms, nil
}
func (a *armyService) ScanBlock(roleId int, req *model.ScanBlockReq) ([]model.Army, error) {
	x := req.X
	y := req.Y
	length := req.Length
	out := make([]model.Army, 0)
	if x < 0 || x >= global.MapWith || y < 0 || y >= global.MapHeight {
		return out, nil
	}

	maxX := utils.MinInt(global.MapWith, x+length-1)
	maxY := utils.MinInt(global.MapHeight, y+length-1)

	a.passBy.RLock()
	defer a.passBy.RUnlock()
	for i := x; i <= maxX; i++ {
		for j := y; j <= maxY; j++ {
			posId := global.ToPosition(i, j)
			armys, ok := a.passByPosArmys[posId]
			if ok {
				//是否在视野范围内
				is := armyIsInView(roleId, i, j)
				if is == false {
					continue
				}
				for _, army := range armys {
					out = append(out, army.ToModel().(model.Army))
				}
			}
		}
	}
	return out, nil
}
func armyIsInView(rid, x, y int) bool {
	//简单点 先设为true
	return true
}
func (a *armyService) GetCreate(cid int, rid int, order int8) (*data.Army, bool) {
	//根据城池id 角色id，order 进行查询
	//有 返回 没有创建并返回
	army, ok := a.GetArmyByCityAndOrder(rid, cid, order)
	if ok {
		return army, true
	}
	//需要创建
	army = &data.Army{
		RId:                rid,
		Order:              order,
		CityId:             cid,
		Generals:           `[0,0,0]`,
		Soldiers:           `[0,0,0]`,
		GeneralArray:       []int{0, 0, 0},
		SoldierArray:       []int{0, 0, 0},
		ConscriptCnts:      `[0,0,0]`,
		ConscriptTimes:     `[0,0,0]`,
		ConscriptCntArray:  []int{0, 0, 0},
		ConscriptTimeArray: []int64{0, 0, 0},
	}
	a.updateGenerals(army)
	err := db.GormDB.Model(army).Create(army).Error
	if err != nil {
		log.Println("armyService GetCreate err", err)
		return nil, false
	}
	return army, true
}
func (a *armyService) GetArmyByCityAndOrder(rid, cId int, order int8) (*data.Army, bool) {
	army := &data.Army{}
	err := db.GormDB.Model(army).Where("rid=? and cityId=? and a_order=?", rid, cId, order).First(army).Error
	if err != nil {
		log.Println("军队查询出错", err)
		return nil, false
	}
	army.CheckConscript()
	a.updateGenerals(army)
	return army, true
}
func (a *armyService) updateGenerals(armys ...*data.Army) {
	for _, army := range armys {
		army.Gens = make([]*data.General, 0)
		for _, gid := range army.GeneralArray {
			if gid == 0 {
				army.Gens = append(army.Gens, nil)
			} else {
				g, _ := GeneralService.Get(gid)
				army.Gens = append(army.Gens, g)
			}
		}
	}
}
func (r *armyService) IsRepeat(rid int, cfgId int) bool {
	armys, err := r.GetDbArmys(rid)
	if err != nil {
		return true
	}
	for _, v := range armys {
		for _, gId := range v.GeneralArray {
			if gId == cfgId {
				return true
			}
		}
	}
	return false
}
func (a *armyService) GetDbArmys(rid int) ([]*data.Army, error) {
	mrs := make([]*data.Army, 0)
	mr := &data.Army{}
	err := db.GormDB.Model(mr).Where("rid=?", rid).Find(&mrs).Error
	if err != nil {
		log.Println("军队查询出错", err)
		return nil, common.New(constant.DBError, "军队查询出错")
	}
	for _, v := range mrs {
		v.CheckConscript()
		a.updateGenerals(v)
	}
	return mrs, nil
}
